package com.maibow.controller.admin;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.sf.json.JSONArray;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.maibow.controller.base.BaseController;
import com.maibow.entity.Page;
import com.maibow.entity.admin.Module;
import com.maibow.entity.admin.OperPrivilege;
import com.maibow.entity.admin.Role;
import com.maibow.entity.admin.SysOperator;
import com.maibow.service.admin.ModuleService;
import com.maibow.service.admin.NewRoleService;
import com.maibow.service.system.CommonService;
import com.maibow.util.CommonConstants;
import com.maibow.util.PageData;

/**
 * 
 * 脉博网络后台管理系统
 * 包名：com.maibow.controller.admin
 * 文件名：NewRoleController.java
 * 作者: 吴比(Wubi)
 * 时间：2015年3月29日-上午10:09:51
 * Copyright@ 2015湖南脉博网络科技有限公司-版权所有
 *
 */
@Controller
@RequestMapping(value = "/newrole")
public class NewRoleController extends BaseController {

    @Resource(name = "moduleService")
    private ModuleService moduleService;

    @Resource(name = "newroleService")
    private NewRoleService roleService;

    @Resource(name = "commonService")
    private CommonService commonService;

    /**
     * 
     * list(角色列表)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@param page
     * 标记：@return
     * 标记：@throws Exception
     * 返回值：ModelAndView
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    @RequestMapping
    public ModelAndView list(Page page) throws Exception {
        ModelAndView modelView = this.getModelAndView();

        SysOperator operator = commonService.getCurrentOperator();
        if (null == operator) {
            modelView.setViewName(this.getRequest().getContextPath() + CommonConstants.MAIN_LOGIN);
        }

        List<Role> roleList = null;
        if (operator.getIsadmin().equals("1")) {
            roleList = roleService.listAllRolesHasSuper(); // 列出所有角色,包括超级管理员
        } else {
            roleList = roleService.listAllRoles(); // 列出所有角色，不包括超级管理员
        }

        getHC();

        modelView.addObject("roleList", roleList);
        modelView.setViewName("system/role/newrole_list");
        return modelView;
    }

    /**
     * 新增页面
     * 
     * @param page
     * @return
     */
    @RequestMapping(value = "/toAdd")
    public ModelAndView toAdd(Page page) {
        ModelAndView modelView = this.getModelAndView();
        PageData pageData = new PageData();
        try {
            pageData = this.getPageData();
            modelView.setViewName("system/role/newrole_add");
            modelView.addObject("pageData", pageData);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return modelView;
    }

    /**
     * 保存新增信息
     */
    @RequestMapping(value = "/addRole", method = RequestMethod.POST)
    public ModelAndView addRole(Role role) throws Exception {
        ModelAndView modelView = this.getModelAndView();
        // PageData pageData = this.getPageData();
        try {
            // pageData =
            // roleService.findMaxId(pageData);
            // role.setRoleId(Integer.parseInt(pageData
            // == null ? "0" :
            // pageData.get("MID").toString()) +
            // 1);
            role.setIsvalid("1");
            //role.setSubsystemid(Integer.valueOf(1));
            roleService.addRole(role);
            modelView.addObject("msg", "success");
        } catch (Exception e) {
            logger.error(e.toString(), e);
            modelView.addObject("msg", "failed");
        }
        modelView.setViewName("save_result");
        return modelView;
    }

    /**
     * 编辑页面
     * 
     * @param roleid
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/toEdit")
    public ModelAndView toEdit(String roleid) throws Exception {
        ModelAndView modelView = this.getModelAndView();
        PageData pageData = new PageData();
        try {
            pageData = this.getPageData();
            pageData.put("roleid", Integer.valueOf(roleid));
            pageData = roleService.findRoleById(pageData);

            modelView.setViewName("system/role/newrole_edit");
            modelView.addObject("pageData", pageData);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
        return modelView;
    }

    /**
     * 编辑页面
     * 
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/editRole")
    public ModelAndView edit() throws Exception {
        ModelAndView modelView = this.getModelAndView();
        PageData pageData = new PageData();
        try {
            pageData = this.getPageData();
            pageData.put("roleid", Integer.valueOf(pageData.get("roleid").toString()));
            pageData = roleService.editRole(pageData);
            modelView.addObject("msg", "success");
        } catch (Exception e) {
            logger.error(e.toString(), e);
            modelView.addObject("msg", "failed");
        }
        modelView.setViewName("save_result");
        return modelView;
    }

    /**
     * 删除
     * 
     * @param roleid
     * @param out
     * @throws Exception
     */
    @RequestMapping(value = "/delete")
    public void deleteRole(@RequestParam String roleid, PrintWriter out) throws Exception {
        PageData pageData = new PageData();
        try {
            pageData.put("roleid", Integer.valueOf(roleid));
            List<PageData> userlist = roleService.listAllUserByRoleId(pageData);
            List<PageData> moduleList = roleService.queryAllModuleRelaByRoleId(Integer.valueOf(roleid));
            if (userlist.size() > 0) {
                out.write("false2");
            } else if (moduleList.size() > 0) {
                out.write("false3");
            } else {
                roleService.deleteRoleById(Integer.valueOf(roleid));
                out.write("success");
            }
            out.flush();
            out.close();
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    /**
     * 请求角色模块、操作权限授权页面
     */
    @RequestMapping(value = "/authModuleAndOper")
    public String authModuleAndOper(@RequestParam String roleid, Model model) throws Exception {

        try {
            // 查找所有模块，包括子模块
            List<Module> moduleList = moduleService.listAllModule();

            // 根据角色查找已授权的模块及操作权限
            List<Module> authedModuleList = roleService.queryAllModulesByRoleId(Integer.valueOf(roleid));

            // 根据角色查找出的模块及操作权限与所有模块及权限进行对比，有的都打上勾
            for (Module module : moduleList) {
                for (Module authedModule : authedModuleList) {
                    if (module.getModuleid() == authedModule.getModuleid()) {
                        module.setHasoperprivilege(true);
                        compareOperPrivilege(module.getOperprivileges(), authedModule.getOperprivileges());

                        // 比较子模块，已授权的就不是子模块了，他们是在同一个列表中
                        compareSubModulePrivilege(module.getSubmodule(), authedModuleList);
                    }
                }
            }

            JSONArray arr = JSONArray.fromObject(moduleList);
            String json = arr.toString();
            json = json.replaceAll("moduletreeid", "id").replaceAll("modulename", "name").replaceAll("submodule", "nodes").replaceAll("operprivilegetreeid", "id").replaceAll("opername", "name")
                                .replaceAll("operprivileges", "nodes").replaceAll("hasoperprivilege", "checked");

            // 把空的节点全部去掉，否则树显示不出来
            json = json.replaceAll(",\"nodes\":\\[\\]", "");
            model.addAttribute("zTreeNodes", json);
            model.addAttribute("roleid", roleid);
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }

        return "system/role/auth_module_oper";
    }

    /**
     * 
     * saveAuth(保存角色菜单权限)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@param roleid
     * 标记：@param menuIds
     * 标记：@param out
     * 标记：@throws Exception
     * 返回值：void
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    @RequestMapping(value = "/authModuleAndOper/save")
    public void saveAuth(@RequestParam String roleid, @RequestParam String moduleids, PrintWriter out) throws Exception {
        try {
            List<Module> authedModuleList = roleService.queryAllModulesByRoleId(Integer.valueOf(roleid));
            if (null != moduleids && !"".equals(moduleids.trim())) {
                // 已存在的所有功能、操作权限ID集合
                List<String> existPrivilegeIds = new ArrayList<String>();

                // 将已存在的所有功能、操作权限ID放到集合中
                putExistPrivilegeId(authedModuleList, existPrivilegeIds);

                // 前端传过来的最新选择的权限ID集合
                String[] privileges = moduleids.split(",");
                String[] inputExistPrivilegeIds = null;
                if (null != existPrivilegeIds && existPrivilegeIds.size() > 0) {
                    inputExistPrivilegeIds = new String[existPrivilegeIds.size()];
                }

                // 循环放到字符品数组中再往下处理
                for (int i = 0; i < existPrivilegeIds.size(); i++) {
                    inputExistPrivilegeIds[i] = (String) existPrivilegeIds.get(i);
                }

                // 需要更新的权限
                List<String> filterResultUpdate = new ArrayList<String>();
                // 需要删除的权限
                List<String> filterResultDelete = new ArrayList<String>();
                // 需要新增的权限
                List<String> filterResultCreate = new ArrayList<String>();

                // 如果选择了权限，要对比当前角色之前拥有的权限。分别抽取出新增、修改(不变)、删除的列表分开执行
                // 对比处理最新选择的权限与原来已存在的权限ID，返回需要新增删除更新的权限结果集
                processFilterResult(inputExistPrivilegeIds, privileges, filterResultUpdate, filterResultDelete, filterResultCreate);

                roleService.saveAuthPrivilege(Integer.valueOf(roleid), filterResultDelete, filterResultCreate);
            } else {
                // 如果没有选择权限，则将角色与功能、操作权限的关联关系全部删除
                roleService.deletePrivilege(Integer.valueOf(roleid), authedModuleList);
            }

            out.write("success");
            out.close();
        } catch (Exception e) {
            logger.error(e.toString(), e);
        }
    }

    /**
     * putExistPrivilegeId(将已存在的权限ID全部加载到列表中)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@param authedModuleList
     * 标记：@param inputExistPrivilegeIds
     * 返回值：void
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void putExistPrivilegeId(List<Module> authedModuleList, List existPrivilegeIds) {
        if (null != authedModuleList && authedModuleList.size() > 0) {
            for (Module authedModule : authedModuleList) {
                existPrivilegeIds.add(authedModule.getModuleid().toString());
                for (OperPrivilege operPrivilege : authedModule.getOperprivileges()) {
                    existPrivilegeIds.add(authedModule.getModuleid().toString() + "-" + operPrivilege.getOperprivilegeid().toString());
                }
                putExistPrivilegeId(authedModule.getSubmodule(), existPrivilegeIds);
            }
        }
    }

    /**
     * 
     * @param moduleList
     * @param authModuleList
     */
    private void compareSubModulePrivilege(List<Module> moduleList, List<Module> authedModuleList) {
        for (Module module : moduleList) {
            for (Module authedModule : authedModuleList) {
                if (module.getModuleid() == authedModule.getModuleid()) {
                    module.setHasoperprivilege(true);
                    compareOperPrivilege(module.getOperprivileges(), authedModule.getOperprivileges());
                }
            }
        }
    }

    /**
     * 
     * @param oerPrivilegeList
     * @param authOerPrivilegeList
     */
    private void compareOperPrivilege(List<OperPrivilege> operPrivilegeList, List<OperPrivilege> authOerPrivilegeList) {
        for (OperPrivilege operPrivilege : operPrivilegeList) {
            for (OperPrivilege authedOperPrivilege : authOerPrivilegeList) {
                if (operPrivilege.getOperprivilegeid() == authedOperPrivilege.getOperprivilegeid()) {
                    operPrivilege.setHasoperprivilege(true);
                }
            }
        }
    }

    /**
     * 
     * processFilterResult(这里用一句话描述这个方法的作用)
     * (这里描述这个方法适用条件 – 可选)
     * 标记：@param inputExistNoteIds
     * 标记：@param inputIds
     * 标记：@param filterResultUpdate
     * 标记：@param filterResultDelete
     * 标记：@param filterResultCreate
     * 返回值：void
     * 作者：吴比(Wubi)
     * 
     * @exception
     * @since 1.0.0
     */
    @SuppressWarnings({ "rawtypes", "unchecked" })
    private void processFilterResult(String[] inputExistNoteIds, String[] inputIds, List filterResultUpdate, List filterResultDelete, List filterResultCreate) {
        if (null != inputExistNoteIds) {
            // 如果已存在的ID列表不为空，但提交的列表为空。代表删除
            if (null == inputIds) {
                for (int i = 0; i < inputExistNoteIds.length; i++) {
                    filterResultDelete.add(inputExistNoteIds[i]);
                }
            } else {
                Map existNoteIdMap = new HashMap();
                for (int i = 0; i < inputExistNoteIds.length; i++) {
                    existNoteIdMap.put(inputExistNoteIds[i], inputExistNoteIds[i]);
                }

                Map existIdsMap = new HashMap();
                for (int j = 0; j < inputIds.length; j++) {
                    existIdsMap.put(inputIds[j], inputIds[j]);
                }

                Iterator iter = existNoteIdMap.entrySet().iterator();
                while (iter.hasNext()) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    Object key = entry.getKey();
                    if (null != existIdsMap.get(key)) {
                        filterResultUpdate.add(key);
                        existIdsMap.remove(key);
                    } else {
                        filterResultDelete.add(key);
                    }
                }

                Iterator iterExistIds = existIdsMap.entrySet().iterator();
                while (iterExistIds.hasNext()) {
                    Map.Entry entry = (Map.Entry) iterExistIds.next();
                    Object key = entry.getKey();
                    filterResultCreate.add(key);
                }
            }
        } else if (null != inputIds) {
            for (int i = 0; i < inputIds.length; i++) {
                filterResultCreate.add(inputIds[i]);
            }
        }
    }

    /*
     * ===============================权限============
     * ======================
     */
    public void getHC() {
        ModelAndView mv = this.getModelAndView();
        // shiro管理的session
        Subject currentUser = SecurityUtils.getSubject();
        Session session = currentUser.getSession();
        List<Module> menuList = (List) session.getAttribute(CommonConstants.SESSION_MODULE_LIST);
        mv.addObject(CommonConstants.SESSION_MODULE_LIST, menuList);// 菜单权限
    }
    /*
     * ===============================权限============
     * ======================
     */
}
